//
//  UIView_public extension.swift
//  AJiTai
//
//  Created by 周博 on 2020/6/17.
//  Copyright © 2020 BO ZHOU. All rights reserved.
//

import UIKit

extension UIView: UIViewProtocol {

}

/**
 * 1. UIView和UILabel的awakeFromXib如果同时被交换, 则两个交换的方法都会执行
 * 2. 父类的运行时交换方法永远都会被执行, (可以在父类中判断类型, 截断子类)
 * 3. 如果父类的运行时方法有交换, 子类不需要重新交换, 因为重新交换也不能截断父类, 可以override重写父类的交换方法, 在里面做自己的事情
 * 4. 子类重写父类的交换方法, 不能调用self.exchange_xxx, 会导致死循环, 要super.exchange_xxx, 父类使用classForCoder判断, 理论上不让super代码在子类中执行
 */

public protocol UIViewProtocol {

}

extension UIViewProtocol where Self: UIView {

    // 从xib中获取uiview实例
    static func viewFromXib() -> Self {

//        let string = NSStringFromClass(self.classForCoder())
//        let string1 = NSStringFromClass(Self.self)
//        let string2 = self.description()
//        let string3 = String(describing: Self.self)  // 只有这个能直接获取到类名转string, 上面三个都是target名.类名
        // 新增: "\(self)"
                
        return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)!.first as! Self
    }
    
    
    /** 寻找和形参相同类型的父类, 就算一个控制器有很多个T类型的view, 该cell的父类T也只有一个, 除非T.addSubView(T)...这种结构 */
    func superViewForClass<T: UIView>(vClass: T.Type) -> T? {
        
        var superV: UIView? = self
        
        repeat {

            superV = superV?.superview
        } while (!(superV?.classForCoder == vClass || superV == nil))
        
        return superV as? T
    }
    
    /** 寻找当前view的父控制器 */
    var superController: UIViewController? {
        
        var responder: UIResponder? = self.next
        
        repeat {
            if (responder?.isKind(of: UIViewController.classForCoder()))! {
                
                return responder as? UIViewController
            }
            responder = responder?.next
        } while((responder) != nil)

        return nil
    }
    
    
    /** 链式编程 (添加自己到superView) */
    func addTo(superView: UIView) {
        superView.addSubview(self)
    }
    
    func add(subviews: [UIView]) {
        for view in subviews {
            addSubview(view)
        }
    }
}

/**
 * 方式2:
 */
//public extension UIView {
//
//    static func viewFromXib1() -> Self {
//
//        return Bundle.main.loadNibNamed(String(describing: Self.self), owner: nil, options: nil)!.last as! Self
//    }
//}


// MARK: UICollectionView 扩展:

//public extension UIViewProtocol where Self: UICollectionView {
//
//    static func collectionView1(
//        itemSize: CGSize,
//        delegate: (UICollectionViewDelegate & UICollectionViewDataSource),
//        cellClass: UICollectionViewCell.Type,
//        minimumLineSpacing: CGFloat = 0,
//        minimumInteritemSpacing: CGFloat = 0,
//        scrollDirection: UICollectionView.ScrollDirection = .horizontal) -> Self {
//
//        let layout = UICollectionViewFlowLayout()
//        layout.itemSize = itemSize
//        layout.minimumLineSpacing = minimumLineSpacing
//        layout.minimumInteritemSpacing = minimumInteritemSpacing
//        layout.scrollDirection = scrollDirection
//
//        let collectionView = Self(frame: .zero, collectionViewLayout: layout)
//        collectionView.delegate = delegate
//        collectionView.dataSource = delegate
//        collectionView.registerCell(cellClass: cellClass)
//
//        return collectionView
//    }
//}



extension UIViewProtocol where Self: UITableView {
    
    static func tableView(stype: UITableView.Style = .plain, delegate: (UITableViewDelegate & UITableViewDataSource)) -> Self {
        
        let tableview = Self(frame: .zero, style: stype)
        tableview.delegate = delegate
        tableview.dataSource = delegate
        
        tableview.separatorStyle = .none
        tableview.backgroundColor = .clear
        
        return tableview
    }
    
}


public extension UICollectionView {
    
    static func collectionView(
        itemSize: CGSize,
        delegate: (UICollectionViewDelegate & UICollectionViewDataSource),
        cellClass: UICollectionViewCell.Type,
        minimumLineSpacing: CGFloat = 0,
        minimumInteritemSpacing: CGFloat = 0,
        scrollDirection: UICollectionView.ScrollDirection = .horizontal) -> Self {
        
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = itemSize
        layout.minimumLineSpacing = minimumLineSpacing
        layout.minimumInteritemSpacing = minimumInteritemSpacing
        layout.scrollDirection = scrollDirection
        
        let collectionView = Self(frame: .zero, collectionViewLayout: layout)
        collectionView.delegate = delegate
        collectionView.dataSource = delegate
        collectionView.registerCell(cellClass: cellClass)
        
        return collectionView
    }
    
    static func collectionView_noSize(
        itemSize: CGSize = CGSize(width: 1, height: 1),
        delegate: (UICollectionViewDelegate & UICollectionViewDataSource),
        cellClass: UICollectionViewCell.Type,
        minimumLineSpacing: CGFloat = 0,
        minimumInteritemSpacing: CGFloat = 0,
        scrollDirection: UICollectionView.ScrollDirection = .horizontal) -> Self {
        
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = itemSize
        layout.minimumLineSpacing = minimumLineSpacing
        layout.minimumInteritemSpacing = minimumInteritemSpacing
        layout.scrollDirection = scrollDirection
        
        let collectionView = Self(frame: .zero, collectionViewLayout: layout)
        collectionView.delegate = delegate
        collectionView.dataSource = delegate
        collectionView.registerCell(cellClass: cellClass)
        
        return collectionView
    }
    
    /**
     * 通过layout快速创建
     */
    static func collectionView_diyLayout(
        delegate: (UICollectionViewDelegate & UICollectionViewDataSource),
        layoutClass: UICollectionViewFlowLayout.Type,
        cellClass: UICollectionViewCell.Type,
        sectionHeaderClass: UICollectionReusableView.Type? = nil,
        sectionFooterClass: UICollectionReusableView.Type? = nil) -> Self  {
        
        
        let collection = UICollectionView(frame: .zero, collectionViewLayout: layoutClass.init())
        collection.delegate = delegate
        collection.dataSource = delegate
        collection.backgroundColor = UIColor.clear
        collection.registerCell(cellClass: cellClass)
        
        if let sectionHeader = sectionHeaderClass {
            collection.register(sectionHeader, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "\(String(describing: sectionHeader))")
        }
        
        if let sectionFooter = sectionFooterClass {
            collection.register(sectionFooter, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "\(String(describing: sectionFooter))")
        }
        
        return collection as! Self
    }
}


// MARK: UITableView 扩展:

public extension UIViewProtocol where Self: UITableView {
    
    static func tableview(delegate: (UITableViewDelegate & UITableViewDataSource)) -> Self {
        
        let tableview: Self = Self()
        tableview.delegate = delegate
        tableview.dataSource = delegate
        tableview.backgroundColor = .clear
        return tableview
    }
}

// MARK: 背景渐变色设置
public extension UIView {
    
    var getGradientLayer: CAGradientLayer? {
        
        if let layers = self.layer.sublayers {
            for layer in layers {
                if layer is CAGradientLayer {
                    return layer as! CAGradientLayer
                }
            }
        }
        return nil
    }
    
    // MARK: 添加渐变色图层
    
    func gradientColorWithHexString(hexStrings: [String], startPoint: CGPoint = CGPoint(x: 0, y: 0), endPoint: CGPoint = CGPoint(x: 1, y: 1)) {
        
        var colors: [CGColor] = []
        
        for colorString in hexStrings {
            colors.append(UIColor.init(hexString: colorString).cgColor)
        }
        
        gradientColor(startPoint: startPoint, endPoint: endPoint, colors: colors)
    }
    
    
    func gradientColor(startPoint: CGPoint = CGPoint(x: 0, y: 0), endPoint: CGPoint = CGPoint(x: 1, y: 1), colors: [Any]) {

        DispatchQueue.main.async {
            
            self.removeGradientLayer()

            let gradientLayer = CAGradientLayer()
            gradientLayer.frame = self.layer.bounds
            gradientLayer.startPoint = startPoint
            gradientLayer.endPoint = endPoint
            gradientLayer.colors = colors
            gradientLayer.cornerRadius = self.layer.cornerRadius
            gradientLayer.masksToBounds = true

            // 渐变图层插入到最底层，避免在uibutton上遮盖文字图片
            self.layer.insertSublayer(gradientLayer, at: 0)
            self.backgroundColor = UIColor.clear

            // self如果是UILabel，masksToBounds设为true会导致文字消失
            self.layer.masksToBounds = false
        }
    }
    
    // MARK: 移除渐变图层
    // （当希望只使用backgroundColor的颜色时，需要先移除之前加过的渐变图层）
    func removeGradientLayer() {
        if let sl = self.layer.sublayers {
            for layer in sl {
                if layer.isKind(of: CAGradientLayer.self) {
                    layer.removeFromSuperlayer()
                }
            }
        }
    }
}




public extension UIView {

    
    //        self.view.add(
    //            .buyButton(withTarget: self, action: #selector(aj_configuration))
    //        )
    @discardableResult
    func add<T: UIView>(_ subview: T, then closure: ((T) -> Void)? = nil) -> T {
        addSubview(subview)
        closure?(subview)
        return subview
    }

    // 例子: 后面可以仿照封装tableview, collectionview, 自定义view等
    static func buyButton(withTarget target: Any, action: Selector) -> UIButton {
        let button = UIButton(type: .custom)
        button.setImage(UIImage(named: "buyimage"), for: .normal)
        button.backgroundColor = .systemGreen
        button.addTarget(target, action: action, for: .touchUpInside)
        return button
    }
}





